package com.rabbiter.fm.controller;

import com.rabbiter.fm.model.IdleItemModel;
import com.rabbiter.fm.vo.ResultVo;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/recommend")
public class RecommendController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    // 计算宠物相似度矩阵
    private Map<Long, Map<Long, Double>> computeItemSimilarity() {
        // 查询所有用户的点击数据
        List<Map<String, Object>> clicks = jdbcTemplate.queryForList("SELECT * FROM user_item_clicks");

        // 构建用户-宠物点击矩阵
        Map<Long, Map<Long, Integer>> userItemMap = new HashMap<>();
        for (Map<String, Object> row : clicks) {
            Long userId = (Long) row.get("user_id");
            Long itemId = (Long) row.get("item_id");
            Integer count = (Integer) row.get("click_count");

            userItemMap.putIfAbsent(userId, new HashMap<>());
            userItemMap.get(userId).put(itemId, count);
        }

        // 计算余弦相似度
        Map<Long, Map<Long, Double>> similarityMatrix = new HashMap<>();
        for (Long itemA : userItemMap.values().stream().flatMap(m -> m.keySet().stream()).collect(Collectors.toSet())) {
            for (Long itemB : userItemMap.values().stream().flatMap(m -> m.keySet().stream()).collect(Collectors.toSet())) {
                if (itemA.equals(itemB)) continue;

                double dotProduct = 0, normA = 0, normB = 0;
                for (Long user : userItemMap.keySet()) {
                    int clickA = userItemMap.get(user).getOrDefault(itemA, 0);
                    int clickB = userItemMap.get(user).getOrDefault(itemB, 0);

                    dotProduct += clickA * clickB;
                    normA += Math.pow(clickA, 2);
                    normB += Math.pow(clickB, 2);
                }

                double similarity = (normA == 0 || normB == 0) ? 0 : dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));

                similarityMatrix.putIfAbsent(itemA, new HashMap<>());
                similarityMatrix.get(itemA).put(itemB, similarity);
            }
        }
        return similarityMatrix;
    }

//    // 获取推荐宠物，支持分页
//    @GetMapping("/{userId}")
//    public ResultVo recommendItems(@PathVariable Long userId,
//                                   @RequestParam(value = "page", required = false) Integer page,
//                                   @RequestParam(value = "nums", required = false) Integer nums) {
//        // 默认分页参数
//        int p = page != null && page > 0 ? page : 1;
//        int n = nums != null && nums > 0 ? nums : 10; // 默认推荐10个宠物
//
//        // 获取用户最近点击的宠物
//        List<Long> recentItems = jdbcTemplate.queryForList(
//                "SELECT item_id FROM user_item_clicks WHERE user_id = ? ORDER BY click_count DESC LIMIT 2",
//                Long.class, userId);
//
//        // 计算相似宠物
//        Map<Long, Map<Long, Double>> similarityMatrix = computeItemSimilarity();
//        Map<Long, Double> recommendedScores = new HashMap<>();
//
//        // 对于没有点击记录的宠物，给予较低优先级的评分
//        Set<Long> allItemIds = new HashSet<>(jdbcTemplate.queryForList("SELECT id FROM sh_idle_item", Long.class));
//
//        // 获取有点击记录的宠物的相似度得分
//        for (Long item : recentItems) {
//            if (!similarityMatrix.containsKey(item)) continue;
//            for (Map.Entry<Long, Double> entry : similarityMatrix.get(item).entrySet()) {
//                recommendedScores.merge(entry.getKey(), entry.getValue(), Double::sum);
//            }
//        }
//
//        // 为没有点击记录的宠物设定较低的默认推荐分数
//        for (Long itemId : allItemIds) {
//            if (!recommendedScores.containsKey(itemId)) {
//                recommendedScores.put(itemId, 0.1);  // 给没有点击记录的宠物一个默认较低分数
//            }
//        }
//
//        // 按照相似度排序，分页处理推荐结果
//        List<Map.Entry<Long, Double>> sortedRecommendations = recommendedScores
//                .entrySet().stream()
//                .sorted((a, b) -> Double.compare(b.getValue(), a.getValue()))
//                .collect(Collectors.toList());
//
//        // 统计推荐结果的总个数
//        int totalCount = sortedRecommendations.size();
//
//        // 分页：计算分页起始位置和结束位置
//        int startIndex = (p - 1) * n;
//        int endIndex = Math.min(startIndex + n, sortedRecommendations.size());
//
//        // 取出分页后的推荐宠物
//        List<Map<String, Object>> recommendedItems = sortedRecommendations.subList(startIndex, endIndex).stream()
//                .map(entry -> jdbcTemplate.queryForMap("SELECT * FROM sh_idle_item WHERE id = ?", entry.getKey()))
//                .collect(Collectors.toList());
//
//        // 返回总推荐数量和分页后的推荐结果
//        Map<String, Object> response = new HashMap<>();
//        response.put("count", totalCount);
//        response.put("list", recommendedItems);
//
//        return ResultVo.success(response);
//    }

    // 获取推荐宠物，支持分页
    @GetMapping("/{userId}")
    public ResultVo recommendItems(@PathVariable Long userId,
                                   @RequestParam(value = "page", required = false) Integer page,
                                   @RequestParam(value = "nums", required = false) Integer nums) {
        System.out.println("通过协同过滤算法进行排序！！！");
        // 默认分页参数
        int p = page != null && page > 0 ? page : 1;
        int n = nums != null && nums > 0 ? nums : 10; // 默认推荐10个宠物

        // 获取用户最近点击的宠物
        List<Long> recentItems = jdbcTemplate.queryForList(
                "SELECT item_id FROM user_item_clicks WHERE user_id = ? ORDER BY click_count DESC LIMIT 2",
                Long.class, userId);

        // 计算相似宠物
        Map<Long, Map<Long, Double>> similarityMatrix = computeItemSimilarity();
        Map<Long, Double> recommendedScores = new HashMap<>();

        // 获取所有状态为 '1' 的宠物 ID
        List<Long> allItemIds = jdbcTemplate.queryForList(
                "SELECT id FROM sh_idle_item WHERE idle_status = '1'", Long.class);
        // 获取有点击记录的宠物的相似度得分
        for (Long item : recentItems) {
            if (!similarityMatrix.containsKey(item)) continue;
            for (Map.Entry<Long, Double> entry : similarityMatrix.get(item).entrySet()) {
                recommendedScores.merge(entry.getKey(), entry.getValue(), Double::sum);
            }
        }
        // 为没有点击记录的宠物设定较低的默认推荐分数
        for (Long itemId : allItemIds) {
            if (!recommendedScores.containsKey(itemId)) {
                recommendedScores.put(itemId, 0.1);  // 给没有点击记录的宠物一个默认较低分数
            }
        }
        // 按照相似度排序
        List<Map.Entry<Long, Double>> sortedRecommendations = recommendedScores
                .entrySet().stream()
                .sorted((a, b) -> Double.compare(b.getValue(), a.getValue()))
                .collect(Collectors.toList());
        // 统计推荐结果的总个数
        int totalCount = sortedRecommendations.size();
        // 分页：计算分页起始位置和结束位置
        int startIndex = (p - 1) * n;
        int endIndex = Math.min(startIndex + n, sortedRecommendations.size());
        // 取出分页后的推荐宠物 ID
        List<Long> recommendedItemIds = sortedRecommendations.subList(startIndex, endIndex).stream()
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
        // 根据推荐宠物 ID 联表查询宠物信息
        StringBuilder idsPlaceholder = new StringBuilder();
        for (int i = 0; i < recommendedItemIds.size(); i++) {
            idsPlaceholder.append("?");
            if (i < recommendedItemIds.size() - 1) {
                idsPlaceholder.append(", ");
            }
        }
        String sql = "SELECT i.*, u.nickname AS creator_name, u.avatar AS avatar " +
                "FROM sh_idle_item i " +
                "JOIN sh_user u ON i.user_id = u.id " +
                "WHERE i.id IN (" + idsPlaceholder.toString() + ") AND i.idle_status = '1'";
        List<Map<String, Object>> recommendedItems = jdbcTemplate.queryForList(
                sql, recommendedItemIds.toArray());
        // 返回总推荐数量和分页后的推荐结果
        Map<String, Object> response = new HashMap<>();
        response.put("count", totalCount);
        response.put("list", recommendedItems);
        return ResultVo.success(response);
    }

    // 获取所有状态为 1 的宠物
    @GetMapping("/all")
    private ResultVo getAllItems(@RequestParam String targetLabel) {
        String sql = "SELECT * FROM sh_idle_item WHERE idle_status = '1'";

        // 查询数据库，返回所有符合条件的结果
        List<IdleItemModel> items = jdbcTemplate.query(sql, (rs, rowNum) -> {
            IdleItemModel item = new IdleItemModel();
            item.setId(rs.getLong("id"));
            item.setIdleName(rs.getString("idle_name"));
            item.setIdleDetails(rs.getString("idle_details"));
            item.setPictureList(rs.getString("picture_list"));
            item.setIdlePrice(rs.getBigDecimal("idle_price"));
            item.setIdlePlace(rs.getString("idle_place"));
            item.setIdleLabel(rs.getInt("idle_label"));
            item.setReleaseTime(rs.getTimestamp("release_time"));
            item.setIdleStatus(rs.getByte("idle_status"));
            item.setUserId(rs.getLong("user_id"));
            item.setChecked(rs.getBoolean("checked"));
            item.setIdleNew(rs.getString("idleNew"));
            // 如果有其他字段，继续设置
            return item;
        });

        // 对结果列表进行排序，将 idleLabel 等于 targetLabel 的项排到最前面
        items.sort((item1, item2) -> {
            // 将 item1 的 idleLabel 转换为字符串并与 targetLabel 比较
            String item1Label = String.valueOf(item1.getIdleLabel());
            String item2Label = String.valueOf(item2.getIdleLabel());

            // 如果 item1 的 idleLabel 等于 targetLabel，则排到最前面
            if (item1Label.equals(targetLabel) && !item2Label.equals(targetLabel)) {
                return -1;  // item1 排在前面
            }
            // 如果 item2 的 idleLabel 等于 targetLabel，则排到最前面
            if (item2Label.equals(targetLabel) && !item1Label.equals(targetLabel)) {
                return 1;  // item2 排在前面
            }
            return 0;  // 对于其他情况，维持原顺序
        });

        return ResultVo.success(items);
    }






}
